home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 2
/
Atari Mega Archive CD - Volume 2.iso
/
minix
/
up1510b.tgz
/
up1510b
/
src
/
commands
/
getty.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-23
|
17KB
|
756 lines
/* getty - get tty speed Author: Fred van Kempen */
/*
* GETTY - Initialize and serve a login-terminal for INIT.
* Also, select the correct speed. The STTY() code
* was taken from stty(1).c; which was written by
* Andrew S. Tanenbaum.
* If this program is called as 'uugetty', then it
* also performs some tasks that are needed before
* UUCP can use the line.
*
* Usage: getty [-c filename] [-h] [-k] [-t] line [speed]
*
* Version: 3.4 02/17/90
*
* Author: F. van Kempen, MicroWalt Corporation
*/
#include <sys/types.h>
#include <sgtty.h>
#include <unistd.h>
#include <utmp.h>
#include <ctype.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <pwd.h>
#ifdef NULL /* ugly, I know... */
# undef NULL
#endif /* NULL */
#define NULL 0
#ifdef SIG_IGN /* even more ugly... */
# undef SIG_IGN
# define SIG_IGN 1
#endif /* SIG_IGN */
#ifndef BITS8 /* new-style UNIX or MINIX */
# define BITS5 CS5
# define BITS6 CS6
# define BITS7 CS7
# define BITS8 CS8
#endif /* BITS8 */
#define GDEFS "/etc/gettydefs" /* pathname of getty definitions */
#define ISSUE "/etc/issue" /* System-name textfile */
#define LOGIN1 "/bin/login"
#define LOGIN2 "/usr/bin/login"
#define COMMENT '#' /* this char starts a comment-line */
#define SEPA '#' /* this char separates the fields */
#define EOT '\004'
#define EOF (char) 0
#define STARTC 021 /* CTRL-Q */
#define STOPC 023 /* CTRL-S */
#define QUITC 034 /* CTRL-\ */
#define EOFC 004 /* CTRL-D */
#define DELC 0177 /* DEL */
#define ST_IDLE 44 /* the getty is idle */
#define ST_RUNNING 55 /* getty is now RUNNING */
#define ST_SUSPEND 66 /* getty was SUSPENDed for dialout */
typedef struct {
char *label; /* label of this entry */
char *flags1; /* initial flags */
char *flags2; /* final flags */
char *prompt; /* login-prompt */
char *next; /* next label in chain */
} ENTRY;
#define clr1 tty.sg_flags &= ~(BITS5 | BITS6 | BITS7 | BITS8)
#define clr2 tty.sg_flags &= ~(EVENP | ODDP)
static char *Version = "@(#) GETTY 3.4 (02/17/90)";
char *tty_name; /* what is our TTY? */
ENTRY gdefs[16]; /* we have space for 16 definitions */
ENTRY *defs; /* our GETTY definition */
int uugetty = 0; /* were we called as 'uugetty' ??? */
int nohup = 0; /* NO hangup on exit/close */
int timeout = 0; /* use TIMEOUT */
int keyboard = 0; /* are we using the Console? */
int state = ST_IDLE; /* the IDLE/SUSPEND/RUNNING state flag */
struct sgttyb tty; /* the current terminal state */
void do_stty(); /* forward declaration */
void sigcatch(sig)
int sig;
{
/* Catch the signals that want to catch. */
switch(sig) {
case SIGEMT: /* SIGEMT means SUSPEND */
if (state == ST_IDLE) state = ST_SUSPEND;
break;
case SIGIOT: /* SIGIOT means RESTART */
if (state == ST_SUSPEND) state = ST_RUNNING;
break;
case SIGBUS: /* SIGBUS means IGNORE ALL */
signal(SIGEMT, SIG_IGN);
signal(SIGIOT, SIG_IGN);
state = ST_RUNNING;
break;
}
signal(sig, sigcatch);
}
char agetchar(fd)
int fd;
{
/* Read a character, or EOF if zero chars read. */
static char buf[1024];
static char *bufp = buf;
static int nleft = 0;
if (nleft == 0) {
nleft = read(fd, buf, 1024);
bufp = buf;
}
return((--nleft >= 0) ? *bufp++ : EOF);
}
char *readline(fd)
int fd;
{
/* Read one line from the defs-file. */
char linbuff[512];
register int c, len;
register char *bp = linbuff;
/* Read a line of text. */
len = 0;
while (1) {
c = agetchar(fd);
if (c == '\n' || c == EOF) break;
*bp++ = c;
len++;
}
*bp = '\0';
/* Now allocate a buffer for it. */
bp = (char *)malloc(len + 1);
if (bp == (char *) NULL) return((char *) NULL);
/* Copy this line to its buffer. */
strcpy(bp, linbuff);
return((c == EOF) ? (char *) NULL : bp);
}
void decode(text, ep)
char *text;
ENTRY *ep;
{
/* Decode an input line. */
register char *sp;
sp = text;
while (*sp == ' ' || *sp == '\t') sp++;
ep->label = sp; /* first, decode LABEL field */
while (*sp != '\0' && *sp != SEPA) sp++;
*sp++ = '\0';
while (*sp == ' ' || *sp == '\t') sp++;
ep->flags1 = sp; /* next, INITIAL flags field */
while (*sp != '\0' && *sp != SEPA) sp++;
*sp++ = '\0';
while (*sp == ' ' || *sp == '\t') sp++;
ep->flags2 = sp; /* then, FINAL flags field */
while (*sp != '\0' && *sp != SEPA) sp++;
*sp++ = '\0';
while (*sp == ' ' || *sp == '\t') sp++;
ep->prompt = sp; /* and the LOGIN_PROMPT field */
while (*sp != '\0' && *sp != SEPA) sp++;
*sp++ = '\0';
while (*sp == ' ' || *sp == '\t') sp++;
ep->next = sp; /* finally, decode the NEXT field */
while (*sp != '\0' && *sp != SEPA) sp++;
*sp++ = '\0';
}
int readdefs(name, label)
char *name;
char *label;
{
/* Read the defs-file. */
int defsfd; /* definition file */
int defidx; /* definition index */
register char *bp;
if ((defsfd = open(name, O_RDONLY)) < 0) return(defsfd);
defidx = 0;
defs = &gdefs[defidx]; /* set DEFAULT definition */
while (1) {
bp = readline(defsfd);
if (bp == (char *) NULL) break;
switch (*bp) {
case '\0': /* blank line */
continue;
case '#': /* comment line */
continue;
default: /* data! */
decode(bp, &gdefs[defidx]);
if (label != (char *) NULL) {
if (!strcmp(gdefs[defidx].label, label))
defs = &gdefs[defidx];
}
defidx++;
}
}
close(defsfd);
return(0);
}
void select()
{
/* Select next speed from the chain. */
register int idx;
idx = 0;
while (idx < 16) {
if (!(strcmp(gdefs[idx].label, defs->next))) {
defs = &gdefs[idx];
do_stty(defs->flags1);
return;
}
idx++;
}
}
void showfile(name)
char *name;
{
/* Read a textfile and show it on the desired terminal. */
register int fd;
register int len;
char buff[1024];
if ((fd = open(name, O_RDONLY)) < 0) return;
while (1) {
len = read(fd, buff, 80);
if (len > 0)
write(1, buff, len);
else
break;
}
close(fd);
}
/* Perform some UTMP and WTMP accounting.
* This information is needed for programs like
* who(1), last(1) and write(1)...
*/
void wtmp(line)
char *line; /* tty device name */
{
struct utmp entry, oldent;
char *blank = " ";
register char *sp;
int fd, recno;
extern long time();
/* Strip off the /dev part of the TTY name. */
sp = strrchr(line, '/');
if (sp == NULL) sp = line;
else sp++;
/* First, read the current UTMP entry. We need some of its
* parameters! (like PID, ID etc...)
*/
if ((fd = open(UTMP, O_RDONLY)) < 0) return;
recno = 0;
while (read(fd, (char *) &oldent, (unsigned) sizeof(struct utmp))
== sizeof(struct utmp)) {
if (oldent.ut_pid == getpid()) break;
recno++;
}
close(fd);
recno *= sizeof(struct utmp);
/* Clear out the new string fields. */
strncpy(entry.ut_name, blank, sizeof(entry.ut_name));
strncpy(entry.ut_id, blank, sizeof(entry.ut_id));
strncpy(entry.ut_line, blank, sizeof(entry.ut_line));
/* Enter new string fields. */
strcpy(entry.ut_name, "");
strncpy(entry.ut_id, oldent.ut_id, sizeof(entry.ut_id));
strncpy(entry.ut_line, sp, sizeof(entry.ut_line));
/* Copy old numeric fields. */
entry.ut_pid = oldent.ut_pid;
/* Change new numeric fields. */
entry.ut_type = LOGIN_PROCESS;/* we are waiting for a LOGIN! */
time((time_t *) &(entry.ut_time));
/* Write a WTMP record. */
if ((fd = open(WTMP, O_WRONLY)) > 0) {
if (lseek(fd, 0L, SEEK_END) >= 0L) {
write(fd, (char *) &entry, sizeof(struct utmp));
}
close(fd);
}
/* Rewrite the UTMP entry. */
if ((fd = open(UTMP, O_WRONLY)) > 0) {
if (lseek(fd, (long) recno, SEEK_SET) >= 0L) {
write(fd, (char *) &entry, sizeof(struct utmp));
}
close(fd);
}
}
/* Read one character from stdin.
* If it looks bad (highest bit set, or error return)
* try next speed in the list.
*/
int areadch()
{
int ch, st;
char ch1;
while (1) {
st = read(0, &ch1, 1); /* read character from TTY */
if (st < 0) return(-1); /* SIGNAL received! */
ch = ch1 & 0xFF;
if (keyboard == 1) return(ch);
if ((ch == 0) || ((ch & 128) == 128)) {
select();
ioctl(0, TIOCGETP, &tty);